package com.shopx.auth.controller;

import com.shopx.auth.DTO.LoginMngDTO;
import com.shopx.auth.DTO.RegDTO;
import com.shopx.auth.bean.SysRole;
import com.shopx.auth.bean.SysUser;
import com.shopx.auth.model.*;
import com.shopx.auth.service.ISysOrgService;
import com.shopx.auth.service.ISysRoleService;
import com.shopx.auth.service.ISysUserService;
import com.shopx.base.anno.RepearSubmitChkAnno;
import com.shopx.base.anno.ShopxParamAnno;
import com.shopx.base.constants.ResultCodeEnum;
import com.shopx.base.controller.BaseController;
import com.shopx.base.dto.FileDTO;
import com.shopx.base.dto.Result;
import com.shopx.base.exception.OriginException;
import com.shopx.base.exception.ShopxException;
import com.shopx.base.utils.ResultUtil;
import com.shopx.cmm.DTO.PageDTO;
import com.shopx.config.bean.SysDict;
import com.shopx.core.DTO.ExcelObjectDTO;
import com.shopx.core.common.CommonConstant;
import com.shopx.core.utils.DateTimeUtil;
import com.shopx.core.utils.ExcelUtil;
import com.shopx.core.utils.GraphicHelper;
import com.shopx.dal.redis.CacheServiceFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

/**
 * @author lituo
 * @className: SysConfigController
 * @description: 用户
 * @date 2021/12/5 12:04 PM
 */
@RestController
@Slf4j
@RequestMapping(value = "/sysUser")
public class SysUserController extends BaseController {

  @Autowired
  private ISysUserService sysUserService;

  @Autowired
  private ISysRoleService sysRoleService;

  @Autowired
  private ISysOrgService sysOrgService;

  @PostMapping(value = "/queryPageList")
  @ShopxParamAnno
  public Result<?> queryPageList(@RequestBody SysUserModel sysUser) throws ShopxException {
    PageDTO<SysUserModel> pageDTO = sysUserService.getListPage(sysUser);
    return ResultUtil.ok(pageDTO);
  }

  @PostMapping(value = "/queryList")
  @ShopxParamAnno
  public Result<?> queryList(@RequestBody SysUserModel sysUser) throws ShopxException {
    List<SysUserModel> list = sysUserService.queryList(sysUser);
    return ResultUtil.ok(list);
  }

  @PostMapping(value = "/queryOrgUserList")
  @ShopxParamAnno
  public Result<?> queryOrgUserList(@RequestBody SysUserModel sysUser) throws ShopxException {
    List<SysUserModel> list = sysUserService.queryOrgUserList(sysUser);
    return ResultUtil.ok(list);
  }

  @PostMapping(value = "/insertOne")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> insertOne(@RequestBody SysUserModel sysUser) throws ShopxException {
    int result = sysUserService.insertSelective(sysUser);
    return ResultUtil.ok(result);
  }


  @PostMapping(value = "/addByMng")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> addByMng(@RequestBody SysUserModel sysUser) throws ShopxException {
    int result = sysUserService.addByMng(sysUser);
    return ResultUtil.ok(result);
  }


  @PostMapping(value = "/updateOne")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> updateOne(@RequestBody SysUserModel sysUser) throws ShopxException {
    int result = sysUserService.updateByPrimaryKeySelective(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/updateUserInfo")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> updateUserInfo(@RequestBody SysUserModel sysUser) throws ShopxException {
    int result = sysUserService.updateUserInfo(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/quit")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> quit(@RequestBody SysUserModel sysUser) throws ShopxException {
    sysUserService.quit(sysUser);
    return ResultUtil.ok(true);
  }

  @PostMapping(value = "/updateIdCard")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> updateIdCard(@RequestBody SysUser sysUser) throws ShopxException {
    int result = sysUserService.updateIdCard(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/userJob")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> userJob(@RequestBody SysUserModel sysUser) throws ShopxException {
    sysUser.setState(CommonConstant.State.EFFECTIVE);
    int result = sysUserService.updateState(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/userQuit")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> userQuit(@RequestBody SysUserModel sysUser) throws ShopxException {
    sysUser.setState(CommonConstant.State.INVALID);
    int result = sysUserService.updateState(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/queryOneByPrimaryKey")
  @ShopxParamAnno
  public Result<?> queryOneByPrimaryKey(@RequestBody SysUserModel sysUser) throws ShopxException {
    SysUserModel result = sysUserService.selectByPrimaryKey(sysUser);
    return ResultUtil.ok(result);
  }

  /**
   * 管理平台登录
   *
   * @param dto
   * @return com.shopx.base.dto.Result<?>
   * @author lituo
   * @date 9:15 AM 2021/12/10
   */
  @PostMapping(value = "/officeLogin")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> officeLogin(@RequestBody @Valid LoginMngDTO dto) {
    SysUserModel userModel = sysUserService.officeLogin(dto);
    return ResultUtil.ok(userModel);
  }

  @PostMapping(value = "/changeCp")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> changeCp(String cpId) {
    SysUserModel sysUserModel = sysUserService.changeCp(cpId);
    return ResultUtil.ok(sysUserModel);
  }

  @PostMapping(value = "/changeRoleType")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> changeRoleType(String roleType) {
    String result = sysUserService.changeRoleType(roleType);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/selectUser")
  @ShopxParamAnno
  public Result<?> selectUser(@RequestBody SysUserModel sysUserModel) {
    SysUserModel userModel = sysUserService.selectUser(sysUserModel);
    return ResultUtil.ok(userModel);
  }

  @PostMapping(value = "/deleteChecked")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> deleteChecked(@RequestBody SysUser sysUser) throws ShopxException {
    int result = sysUserService.deleteByPrimaryKey(sysUser);
    return ResultUtil.ok(result);
  }

  @PostMapping(value = "/deleteBatch")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  public Result<?> deleteBatch(@RequestBody List<SysUser> list) {
    sysUserService.deleteBatch(list);
    return ResultUtil.ok(true);
  }

  @PostMapping(value = "/changePswd")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> changePswd(@RequestBody SysUserModel user) {
    sysUserService.changePswd(user);
    return ResultUtil.ok(true);
  }

  @PostMapping(value = "/changePswdByAdmin")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> changePswdByAdmin(@RequestBody SysUserModel user) {
    sysUserService.changePswdByAdmin(user);
    return ResultUtil.ok(true);
  }

  @PostMapping(value = "/selectListByRoleCode")
  @ShopxParamAnno
  public Result<?> selectListByRoleCode(@RequestBody SysUserModel sysUser) throws ShopxException {
    List<SysUserModel> list = sysUserService.selectListByRoleCode(sysUser);
    return ResultUtil.ok(list);
  }

  /**
   * 生成登录验证码
   *
   * @return com.shopx.base.dto.Result<?>
   * @author lituo
   * @date 9:02 PM 2021/12/9
   */
  @GetMapping(value = "/genRandomCode")
  public void genRandomCode(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //获取key
    OutputStream output = null;
    try {
      String codeKey = request.getParameter("codeKey");
      output = response.getOutputStream();
      String randomCode = GraphicHelper.genCode(180, 60, output);
      CacheServiceFactory.getCacheService().set(codeKey, randomCode, 120);
    } catch (Exception e) {
      log.error("genRandomCode.error:{}", e);
      throw new OriginException("99999", "获取验证码失败");
    } finally {
      if (output != null) {
        output.flush();
        output.close();
      }
    }

  }

  /**
   * @param dto
   * @return com.shopx.base.dto.Result<?>
   * @descript 企业注册
   * @author lituo
   * @date 2022/1/4 14:57
   */
  @PostMapping(value = "/reg")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> reg(@RequestBody @Valid RegDTO dto) throws ShopxException {
    sysUserService.userReg(dto);
    return ResultUtil.ok(true);
  }

  /**
   * @param sysUser
   * @param response
   * @return void
   * @descript 导出用户数据
   * @author lituo
   * @date 2021/12/21 15:21
   */
  @RequestMapping(value = "/download")
  public void download(SysUserModel sysUser, HttpServletResponse response) {
    ExcelObjectDTO dto = new ExcelObjectDTO();
    dto.setSubTitle("员工导出清单");
    dto.setTitle(new String[]{"loginName:电话号码", "roleNames:角色", "userName:姓名", "entryTm:入职时间", "quitTm:离职时间", "cpName:所在公司", "orgName:所在部门", "stateDesc:状态"});
    PageDTO<SysUserModel> pageDTO = sysUserService.getListPage(sysUser);
    dto.setObj(pageDTO.getData());
    dto.setSize(pageDTO.getiTotalDisplayRecords());
    ResultUtil.excelDownload(dto, response);
  }


  /**
   * 导出模板
   *
   * @param response
   * @return void
   * @author lituo
   * @date 8:23 PM 2022/1/29
   */
  @RequestMapping(value = "/downloadUserTemplate")
  public void downloadUserTemplate(HttpServletResponse response) throws ShopxException {
    HSSFWorkbook wb = null;
    OutputStream os = null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try {
      byte[] ba = baos.toByteArray();
      wb = this.generatorTemplate();
      os = response.getOutputStream();
      baos.flush();
      wb.write(baos);
      ba = baos.toByteArray();
      response.reset();// 重置response
      response.setContentType("text/html;charset=UTF-8");
      response.setHeader("Content-Disposition", "attachment;filename=" + DateTimeUtil.getDateTime14() + ".xlsx");
      response.setContentType("application/x-msdownload");
      os.write(ba);// 导出
    } catch (Exception e) {
      log.info("download.error", e);
      throw new ShopxException(ResultCodeEnum.EXPORT_ERROR);
    } finally {
      if (null != baos) {
        try {
          baos.close();
        } catch (IOException e) {
          log.info("baos.close.error", e);
        }
      }
      if (null != os) {
        try {
          os.close();
        } catch (IOException e) {
          log.info("os.close.error", e);
        }
      }
      if (response != null) {
        try {
          response.getWriter().close();
        } catch (IOException e) {
          log.info("response.close.error", e);
        }
      }
    }
  }

  /**
   * 生成导出excel模板
   *
   * @param
   * @return org.apache.poi.hssf.usermodel.HSSFWorkbook
   * @author lituo
   * @date 8:23 PM 2022/1/29
   */
  private HSSFWorkbook generatorTemplate() {
    HSSFWorkbook wb = new HSSFWorkbook();
    CellStyle cellTitleStyle = ExcelUtil.getTitleCellStyle(wb);
    CellStyle cellStrStyle = ExcelUtil.getCmmCellStyle(wb);
    Sheet sheet = wb.createSheet("导入用户清单");

    Row row = sheet.createRow(0);
    String cols[] = new String[]{"电话号码", "身份证号码", "用户姓名", "所在部门", "入职时间(如20220101)", "角色(多个角色用逗号分割)", "收款方式(1:网银;2:微信;3:支付宝)", "结算银行卡号(微信支付宝填手机号)", "结算银行开户行", "结算银行开户分行", "结算银行户名", "已缴纳押金(数字)", "应缴押金金额(数字)"};
    for (int i = 0; i < cols.length; i++) {
      sheet.setDefaultColumnStyle(i, cellStrStyle);
      ExcelUtil.createCell(wb, row, i, cols[i], cellTitleStyle);
    }
    //查询角色
    Sheet sheet2 = wb.createSheet("企业角色");
    Row row2 = sheet2.createRow(0);
    ExcelUtil.createCell(wb, row2, 0, "角色编码（填写此项）", cellTitleStyle);
    ExcelUtil.createCell(wb, row2, 1, "角色名称", cellTitleStyle);
    List<SysRoleModel> roleList = sysRoleService.queryList(null);
    for (int j = 0; j < roleList.size(); j++) {
      sheet2.setDefaultColumnStyle(1, cellStrStyle);
      sheet2.setDefaultColumnStyle(0, cellStrStyle);
      Row rows = sheet2.createRow(j + 1);
      ExcelUtil.createCell(wb, rows, 0, roleList.get(j).getRoleCode(), cellStrStyle);
      ExcelUtil.createCell(wb, rows, 1, roleList.get(j).getRoleName(), cellStrStyle);
    }
    //查询部门
    Sheet sheet3 = wb.createSheet("企业部门");
    Row row3 = sheet3.createRow(0);
    ExcelUtil.createCell(wb, row3, 0, "部门编码（填写此项）", cellTitleStyle);
    ExcelUtil.createCell(wb, row3, 1, "部门名称", cellTitleStyle);
    SysOrgModel som = new SysOrgModel();
    List<SysOrgModel> orgList = sysOrgService.getListPage(som).getData();
    for (int j = 0; j < orgList.size(); j++) {
      sheet3.setDefaultColumnStyle(0, cellStrStyle);
      sheet3.setDefaultColumnStyle(1, cellStrStyle);
      Row rows = sheet3.createRow(j + 1);
      ExcelUtil.createCell(wb, rows, 0, orgList.get(j).getOrgId(), cellStrStyle);
      ExcelUtil.createCell(wb, rows, 1, orgList.get(j).getOrgName(), cellStrStyle);

    }
//    for (int k = 1; k < 50000; k++) {
//      for (int i = 0; i < cols.length; i++) {
//        ExcelUtil.createCell(wb, sheet.createRow(k), i, "", cellStrStyle);
//      }
//    }
    return wb;
  }

  /**
   * @param fileDTO
   * @return com.shopx.base.dto.Result<?>
   * @descript 批量写入用户数据
   * @author lituo
   * @date 2021/12/21 16:36
   */
  @PostMapping(value = "/batchWriteUser")
  @RepearSubmitChkAnno(lockTime = CommonConstant.REQ_TM)
  @ShopxParamAnno
  public Result<?> batchWriteUser(@RequestBody FileDTO fileDTO) throws Exception {
    sysUserService.batchWriteUser(fileDTO.getFilePath());
    return ResultUtil.ok(true);
  }

  /**
   * @param userId
   * @return com.shopx.base.dto.Result<?>
   * @descript 验证员工角色是否是店铺或者施工部
   * @author lituo
   * @date 2022/3/7 16:26
   */
  @PostMapping(value = "/chkUserSOFlag")
  @ShopxParamAnno
  public Result<?> chkUserSOFlag(String userId) {
    List<SysRole> list = sysUserService.chkUserSOFlag(userId);
    return ResultUtil.ok(list);
  }

  /**
   * @return com.shopx.base.dto.Result<java.util.List < com.shopx.auth.model.SysUserCpModel>>
   * @desc 查询用户公司列表
   * @author lituo
   * @date 2023/5/23 10:38 下午 @param loginMngDTO
   */
  @PostMapping(value = "/selectUserCpList")
  public Result<List<SysUserCpModel>> selectUserCpList(@RequestBody @Valid LoginMngDTO loginMngDTO) {
    List<SysUserCpModel> list = sysUserService.selectUserCpList(loginMngDTO);
    return ResultUtil.ok(list);
  }

  @PostMapping(value = "/selectListByRoleType")
  public Result<List<SysUserCpModel>> selectListByRoleType(@RequestBody SysUserModel sysUserModel) {
    List<SysUserModel> list = sysUserService.selectListByRoleType(sysUserModel);
    return ResultUtil.ok(list);
  }

  @PostMapping(value = "/createRegCode")
  public Result<?> createRegCode(@RequestBody SysUser sysUser) {
    String vCode = sysUserService.createRegCode(sysUser);
    return ResultUtil.ok(vCode);
  }

}

